package org.d8s.magicapi.listener;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.util.ClassUtil;
import org.d8s.magicapi.aop.MagicApiClusterAspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.config.MappingHandlerMapping;
import org.ssssssss.magicapi.provider.ApiServiceProvider;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 消息监听
 *
 * @author 冰点
 * @date 2021-5-20 17:52:46
 * @since 1.1.1
 */
@Component
public class RedisMessageListener implements MessageListener {
    private static final Logger log = LoggerFactory.getLogger(RedisMessageListener.class);
    @Autowired
    public MappingHandlerMapping mappingHandlerMapping;
    @Autowired
    private ApiServiceProvider magicApiService;
    private Map<String, Method> MethodMap;
    @Value("${magic-plugin.cluster.enableGlobalRefresh:true}")
    private boolean enableGlobalRefresh;

    @PostConstruct
    public void initRedisMessageListener() {
        Method[] methods = ClassUtil.getDeclaredMethods(ApiServiceProvider.class);
        MethodMap = Arrays.stream(methods).collect(Collectors.toMap(Method::getName, Function.identity(), (key1, key2) -> key1));
    }


    @Override
    public void onMessage(Message message, byte[] pattern) {
        String body = null;
        try {
            body = new String(message.getBody());
            log.info("接口信息变动，更新当前内存数据 message:[{}]", body);
            Map<String, String> map = JSON.parseObject(body, Map.class);
            if (map.containsValue(MagicApiClusterAspect.INSTANCE_ID)) {
                log.info("接口信息变动为当前实例发起的通知，不用更新缓存:[{}]", body);
            } else {
                log.info("接口信息变动，更新当前内存数据 message:[{}]", body);
                if (enableGlobalRefresh) {
                    mappingHandlerMapping.registerAllMapping();
                } else {
                    Method method = MethodMap.get(map.get("method"));
                   List<Object> params= JSON.parseArray(map.get("params"),Object.class);
                    method.invoke(magicApiService, params.toArray());
                }

            }
        } catch (Exception e) {
            log.error("接口信息变动，更新当前内存数据失败，请重启服务完成更新message:[{}]", body);
        }

    }
}